/*
	This file is part of "Ants on the web".

    "Ants on the web" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "Ants on the web" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with "Ants on the web".  If not, see <http://www.gnu.org/licenses/>.
*/

package org.utc.ia04.antsontheweb.antColonyOptimisation.antColony;


import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;

import org.utc.ia04.antsontheweb.antColonyOptimisation.ant.AntAgent;
import org.utc.ia04.antsontheweb.gui.surveillance.AgentInterfaceSurveillance;
import org.utc.ia04.antsontheweb.knowledgeBase.KnowledgeBaseAgent;
import org.utc.ia04.antsontheweb.utilities.Requete;

import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.wrapper.AgentContainer;
import jade.wrapper.AgentController;

public class AntColonyAgent extends Agent
{
	//serialVersionUID
	private static final long serialVersionUID = -3357304401046597511L;
	
	//Default parameters
	public static final int DEFAULT_NB_ANTS = 5;
	public static final int DEFAULT_TICK = 200;
	public static final int DEFAULT_COLLECTED_RESSOURCE_MAX = 10;
	public static final int DEFAULT_WEBSITE_TYPE = KnowledgeBaseAgent.BUYING_SITE;
	public static final String DEFAULT_URL = "http://www.rue89.com/";
	
	//DF informations
	public static final String dfType = "AntColony";
	
	//attributes
	private int AntMax;
	private int AntNumber;
	private int RessourceCollectedMax;
	private int RessourceCollectedNb;
	private int websiteType;
	private long period;
	private long tickerTime;
	private URL url;
	private long antLifeExtancy;
	private long antLifeExtancyVar;
	
	//methods
	public void setup()
	{
		Object[] args = getArguments();
		AntMax = (Integer) args[0];
		AntNumber = 0;
		RessourceCollectedMax = (Integer) args[1];
		RessourceCollectedNb = 0;
		period = (Integer) args[2];
		websiteType = (Integer) args[3];
		antLifeExtancy = (Long) args[5];
		antLifeExtancyVar = (Long) args[6];
		tickerTime = 0;
		try {
			url = new URL(args[4].toString());
		} catch (MalformedURLException e) {
			 //TODO Auto-generated catch block
			e.printStackTrace();
		}
		addBehaviour(new AntColonyBhv(this, period));
		addBehaviour(new InformMsgReceptionBhv());
		register();
	}
	
	private void createAnt(String parName)
	{
		Object [] args = new Object[6];
		args[0] = url;
		args[1] = tickerTime;
		args[2] = this.getName();
		args[3] = websiteType;
		args[4] = antLifeExtancy;
		args[5] = antLifeExtancyVar;
	 
        AgentContainer c =  getContainerController();
        try {
            AgentController a = c.createNewAgent(parName, "org.utc.ia04.antsontheweb.antColonyOptimisation.ant.AntAgent", args );
            a.start();
            AntNumber++;
        }
        catch (Exception e)
        {
        	System.out.println(e.getMessage());
        }
	}
	
	void createAnts()
	{
		for (int i = 0; i<getNbAntToCreate(); ++i)
		{
			UUID id = UUID.randomUUID();
			createAnt("Ant_"+id.toString());
		}
	}
	
	int getNbAntToCreate()
	{
		return AntMax - AntNumber;
	}
	
	boolean enougthCollectedResource()
	{
		return RessourceCollectedNb == RessourceCollectedMax;
	}
	
	void incRessourceCollectedNb ()
	{
		RessourceCollectedNb++;
		informBigBrotherTerminals();
	}
	
	void decAntNumber ()
	{
		AntNumber--;
	}
	
	public int getCollectedRessource()
	{
		return RessourceCollectedNb;
	}
	
	void incTickerTime ()
	{
		tickerTime++;
	}
	
	long getTickerTime(){return tickerTime;}
	
	private void register()
	{
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());
		ServiceDescription sd = new ServiceDescription();
		sd.setType(dfType); sd.setName(this.getName());
		dfd.addServices(sd);
		try { DFService.register(this, dfd); }
		catch (Exception fe) 
		{
			System.out.println(fe.getMessage());
		}
	}
	
	protected void takeDown()
	{
		ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
		Requete query = new Requete(Requete.AC_DEATH,"GET_DEAD");
		msg.setContent(query.serialize());
		
		DFAgentDescription template = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();
		sd.setType(AntAgent.DF_TYPE);
		template.addServices(sd);
		try
		{
			DFAgentDescription[] result = DFService.search(this, template);
			for(int i = 0; i < result.length; ++i)
				msg.addReceiver(result[i].getName());
		}
		catch(Exception fe)
		{ System.out.println(fe.getMessage()); }
		send(msg);
		
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());

		try { DFService.deregister(this, dfd); }
		catch (FIPAException e) { }
	}
	
	private void informBigBrotherTerminals()
	{
		//Requete
		ACLMessage message = new ACLMessage(ACLMessage.INFORM);
		Requete req = new Requete(Requete.INFORM_BIG_BROTHER, String.valueOf(RessourceCollectedNb));
		message.setContent(req.serialize());
		
		//Destinataire
		DFAgentDescription template = new DFAgentDescription();
		ServiceDescription sd = new ServiceDescription();
		sd.setType(AgentInterfaceSurveillance.DF_TYPE);
		template.addServices(sd);
		try
		{
			DFAgentDescription[] result = DFService.search(this, template);
			for(int i = 0; i < result.length; ++i)
				message.addReceiver(result[i].getName());
		}
		catch(Exception fe) {}
		
		//Envoie
		send(message);
	}
}
